module TP where

import Arbol23
							
-- Ejercicio 1
foldA23 :: (a -> d ) -> (b -> d -> d -> d ) -> (b -> b -> d -> d -> d -> d) -> (Arbol23 a b)  -> d
foldA23 fHoja _ _ (Hoja x)              = fHoja x
foldA23 fHoja fDos fTres (Dos x izq der)   = fDos x (foldA23 fHoja fDos fTres izq) (foldA23 fHoja fDos fTres der)
foldA23 fHoja fDos fTres (Tres x y izq med der)   = fTres x y 
                                                    (foldA23 fHoja fDos fTres izq) 
                                                    (foldA23 fHoja fDos fTres med)
                                                    (foldA23 fHoja fDos fTres der)

-- Ejercicio 2

hojas::Arbol23 a b->[a]
hojas = foldA23(\n -> [n])(\x rec_izq rec_der -> rec_izq ++ rec_der)(\x y rec_izq rec_med rec_der -> rec_izq ++ rec_med ++ rec_der)

internos::Arbol23 a b -> [b]
internos = foldA23 (\n -> [])(\x rec_izq rec_der -> [x] ++ rec_izq ++ rec_der)(\x y rec_izq rec_med rec_der -> [x,y] ++ rec_izq ++ rec_med ++ rec_der)

esHoja::Arbol23 a b -> Bool
esHoja = foldA23(\_ -> True)(\_ _ _ -> False)(\_ _ _ _ _ -> False)

-- Ejercicio 3
mapA23::(a->c)->(b->d)->Arbol23 a b->Arbol23 c d
mapA23 fHoja fNodo = 	foldA23(\x -> Hoja (fHoja x))
						(\x rec_izq rec_der -> Dos (fNodo x) rec_izq rec_der)
						(\x y rec_izq rec_med rec_der -> Tres (fNodo x) (fNodo y) rec_izq rec_med rec_der)				
-- Ejercicio 4

foldNat :: (b -> b) -> b -> Integer -> b
foldNat s z 0 = z
foldNat s z n = s (foldNat s z (n-1))

truncarBase::a->Arbol23 a b->Arbol23 a b
truncarBase a _ = Hoja a
  
truncarAux::(Arbol23 a b->Arbol23 a b)->Arbol23 a b->Arbol23 a b
truncarAux f (Hoja x)= (Hoja x)
truncarAux f (Dos x izq der)= Dos x (f izq) (f der)
truncarAux f (Tres x y izq med der)= Tres x y (f izq) (f med) (f der)

truncar2::a->Integer->Arbol23 a b->Arbol23 a b
truncar2 a n arbol= (foldNat truncarAux (truncarBase a)) n arbol

-- Ejercicio 5
-- Para poder utilizar e Sacadpo de Arbol23.hs
--incrementarHojas::Num a =>Arbol23 a b->Arbol23 a b
--incrementarHojas = mapA23 (+1) id

--arbolito3::Arbol23 Int (Int->Int->Int)
--arbolito3 = Dos (+) (Tres (*) (-) (Hoja 1) (Hoja 2) (Hoja 3)) (incrementarHojas arbolito3)

--Definicion para usar con el foldA23 para arboles construidos con el constructor Dos
-- evalDos::(a->a->a)->a->a->a
-- evalDos x izq der= x izq der 
-- 
-- --Definicion para usar con el foldA23 para arboles construidos con el constructor Tres
-- evalTres::(a->a->a)->(a->a->a)->a->a->a->a
-- evalTres x y izq med der= y (x izq med) der
-- 
-- evaluar::Arbol23 a (a->a->a)->a
-- evaluar arbol= foldA23 id evalDos evalTres arbol						
												
-- 												
												
												
												
												
												
												
												
												
												
